package org.bing.zion.filter.comsat;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class ComsatDecoder extends ComsatCodec {

	/**
	 * Format {item:MD-MA-INVOCATION,host:127.0.0.1,date:2010-09-09 12:23:32,desc:"some desc, more!",name:somepage,count:123}
	 */

	public Object decode(byte[] buf) throws IOException { 
		ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length);
		baos.write(buf);
		return this.decode(baos);
	}
	
	public Object decode(ByteArrayOutputStream baos) throws IOException { 
		byte[] total = baos.toByteArray(); 
		int limit = total.length, first = 0;
		// locate first flag '{'
		for (int k = 0; k < limit; k++) {
			byte c = total[k];
			if (c == '{') {
				first = k + 1;
				break;
			} else if (!Character.isWhitespace(c)) {
				throw new RuntimeException("Appear incorrect char:" + (char) c + "," + new String(total));
			}
		}

		Map<String, String> map = new HashMap<String, String>();
		// lookup key/value pair
		StringBuilder sb = new StringBuilder(32);
		String currKey = null, currValue = null;
		boolean flag = false;
		for (int i = first; i < limit; i++) {
			char c = (char) total[i];
			if (c == '\\') { // control-character
				sb.append((char) total[++i]);
			} else if (c == ':') { // key
				currKey = sb.toString();
				sb = new StringBuilder();
			} else if (c == ',') { // value
				currValue = sb.toString();
				map.put(currKey, currValue);
			} else if (c == '}') {
				currValue = sb.toString();
				map.put(currKey, currValue);
				flag = true;
				baos.reset(); // reset baos
				if (i != limit - 1) {
					baos.write(total, i + 1, limit - i - 1);
				}
				break; // end of item
			} else {
				sb.append(c);
			}
		} 
		return flag ? map : null;
	}
}
